home *** CD-ROM | disk | FTP | other *** search
/ Keyframe Magazine 6 / KeyFrame Magazine, Issue 6 - May-June 1998 WIN-MAC (David Warner)(1998).iso / mac / ProgHide / default.cpp next >
C/C++ Source or Header  |  1997-06-23  |  8KB  |  306 lines

  1. //Includes
  2. #include <splug.h>
  3. #include <moni.h>
  4. #include <lwran.h>
  5. #include <lwpanel.h>
  6. #include <strstrea.h>
  7.  
  8. //Typedefs
  9. typedef unsigned short int USHORT;
  10.  
  11. //Defines
  12. #define NULL 0
  13.  
  14. //Global constant (reduces string table size)
  15. const char * const SPACE = " ";
  16.  
  17. //Function prototypes
  18. //
  19. extern "C"
  20. {
  21.     int                GRADActivate(long, GlobalFunc *, void *, void *);
  22.     int                GRADInterface(long, GlobalFunc *, LWInstance, void *);
  23. }
  24.  
  25. LWInstance            GRADcreate(LWError *);
  26. void                GRADdestroy(LWInstance);
  27. LWError                GRADcopy(LWInstance, LWInstance);
  28. LWError                GRADload(LWInstance, const LWLoadState *);
  29. LWError                GRADsave(LWInstance, const LWSaveState *);
  30. const char*            GRADdescln(LWInstance);
  31. void                GRADprocess(LWInstance, const FilterAccess *);
  32. unsigned int        GRADflags(LWInstance);
  33.  
  34.  
  35. //Most plugins have a structure or class they store data in.  This is called the instance.
  36. //
  37. class GRADIENT
  38. {
  39. public:
  40.     //Gradient colors at the top and bottom of the image
  41.     USHORT cTop[3], cBottom[3];
  42.  
  43. private:
  44. };
  45.  
  46.  
  47. //The ServerRecord structure identifies all the plugins in this file to Lightwave.
  48. extern "C"
  49. {
  50. ServerRecord ServerDesc[] = 
  51. {
  52.     { "ImageFilterHandler",    "LightWavin_gradient",    GRADActivate },
  53.     { "ImageFilterInterface",    "LightWavin_gradient",    GRADInterface },
  54.     { NULL }
  55. };
  56. }
  57.  
  58.  
  59. //These globals allow you to use the macros to add controls in the interface.
  60. static LWPanControlDesc   desc;                                 
  61. static LWValue ival={LWT_INTEGER},ivecval={LWT_VINT},
  62.   fval={LWT_FLOAT},fvecval={LWT_VFLOAT},sval={LWT_STRING};
  63.  
  64.  
  65. //Activation function.  This function tells Lightwave where to find all the
  66. //functions it needs to run the plugin.
  67. //
  68. int GRADActivate(
  69.     long            version,
  70.     GlobalFunc        *global,
  71.     void            *locPtr,
  72.     void            *data
  73.     )
  74. {
  75.         ImageFilterHandler *local = reinterpret_cast<ImageFilterHandler *>(locPtr);
  76.  
  77.         if(version != 2) return AFUNC_BADVERSION;
  78.  
  79.         local->create     = GRADcreate;
  80.         local->destroy     = GRADdestroy;
  81.         local->copy        = GRADcopy;
  82.         local->load        = GRADload;
  83.         local->save        = GRADsave;
  84.         local->descln    = GRADdescln;
  85.  
  86.         local->process    = GRADprocess;
  87.         local->flags    = GRADflags;
  88.  
  89.         return AFUNC_OK;
  90. }
  91.  
  92. //Creation function
  93. LWInstance GRADcreate(LWError *error)
  94. {
  95.     GRADIENT *inst = new GRADIENT;
  96.     return(reinterpret_cast<LWInstance>(inst));
  97. }
  98.  
  99.  
  100. //Destroy function
  101. void GRADdestroy(LWInstance inst)
  102. {
  103.     if(inst)
  104.     {
  105.         GRADIENT *instToDelete = reinterpret_cast<GRADIENT *>(inst);
  106.         delete instToDelete;
  107.         return;
  108.     }
  109.     return;
  110. }
  111.  
  112.  
  113. //Copy function
  114. LWError GRADcopy(LWInstance from, LWInstance to)
  115. {
  116.     GRADIENT *first, *second;
  117.     first = reinterpret_cast<GRADIENT *>(from);
  118.     second = reinterpret_cast<GRADIENT *>(to);
  119.     *second = *first;
  120.     return NULL;
  121. }
  122.  
  123.  
  124. //Save function.
  125. LWError GRADsave(LWInstance inst, const LWSaveState *lwss)
  126. {
  127.     //Convert the instance pointer
  128.     GRADIENT *defInst = reinterpret_cast<GRADIENT*>(inst);
  129.  
  130.     //Allocate the output string
  131.     char cOutputString[32];
  132.  
  133.     //Enter the data
  134.     ostrstream ostr(cOutputString, 32);
  135.  
  136.     ostr << defInst->cTop[0] << SPACE << defInst->cTop[1] << SPACE;
  137.     ostr << defInst->cTop[2];
  138.     ostr << SPACE << defInst->cBottom[0] << SPACE << defInst->cBottom[1];
  139.     ostr << SPACE << defInst->cBottom[2] << ends;
  140.  
  141.     //Write the data to the scene file
  142.     lwss->write(lwss->writeData, cOutputString, 32);
  143.  
  144.     return NULL;
  145. }
  146.  
  147. //Load function
  148. LWError GRADload(LWInstance inst, const LWLoadState *lwls)
  149. {
  150.     //Convert the instance pointer
  151.     GRADIENT *defInst = reinterpret_cast<GRADIENT*>(inst);
  152.  
  153.     //Allocate the input string
  154.     char cInputString[32];
  155.  
  156.     //Get the data from the scene file
  157.     lwls->read(lwls->readData, cInputString, 32);
  158.  
  159.     //Extract the data into the instance
  160.     istrstream istr(cInputString, 32);
  161.     istr >> defInst->cTop[0] >> defInst->cTop[1] >> defInst->cTop[2];
  162.     istr >> defInst->cBottom[0] >> defInst->cBottom[1] >> defInst->cBottom[2];
  163.  
  164.     return NULL;
  165. }
  166.  
  167. //Returns a descriptive line for the plugin
  168. const char* GRADdescln(LWInstance inst)
  169. {
  170.     return "Lightwavin' Plugin Tutorial";
  171. }
  172.  
  173.  
  174. //Tells LW which buffers the plugin will need
  175. unsigned int        GRADflags(LWInstance inst)
  176. {
  177.     return NULL;
  178. }
  179.  
  180.  
  181. //Process - The fun stuff!
  182. void    GRADprocess(LWInstance inst, const FilterAccess *fa)
  183. {
  184.     //Convert the instance
  185.     GRADIENT *defInst = reinterpret_cast<GRADIENT*>(inst);
  186.  
  187.     //BufferValue pointers to process the image
  188.     BufferValue         out[3], *r, *g, *b, *a;
  189.  
  190.     //Create the monitor for our use
  191.     Monitor *mon = fa->monitor;
  192.  
  193.     //Initialize the monitor
  194.     MON_INIT (mon, fa->height);
  195.  
  196.     //Loop through the lines in the image
  197.     for (USHORT i = 0; i < fa->height; i++) {
  198.         r = fa->bufLine(LWBUF_RED,   i);
  199.         g = fa->bufLine(LWBUF_GREEN, i);
  200.         b = fa->bufLine(LWBUF_BLUE,  i);
  201.         a = fa->bufLine(LWBUF_ALPHA, i);
  202.  
  203.         //This is the current percentage of the image that this line is
  204.         double dPercent = i;
  205.         dPercent /= fa->height;
  206.  
  207. #pragma warning(disable : 4244)
  208.  
  209.         //Blend the gradient values
  210.         unsigned char currR = (defInst->cTop[0] * (1 - dPercent)) +
  211.             (defInst->cBottom[0] * dPercent );
  212.         unsigned char currG = (defInst->cTop[1] * (1 - dPercent)) +
  213.             (defInst->cBottom[1] * dPercent );
  214.         unsigned char currB = (defInst->cTop[2] * (1 - dPercent)) +
  215.             (defInst->cBottom[2] * dPercent );
  216.  
  217. #pragma warning(default : 4244)
  218.  
  219.         //Divide the gradient by two (for a 50% blend with the image)
  220.         currR /= 2;
  221.         currG /= 2;
  222.         currB /= 2;
  223.  
  224.         //Loop through the pixels in the line
  225.         for (USHORT j = 0; j < fa->width; j++)
  226.         {
  227.             out[0] = (r[j] / 2) + currR;
  228.             out[1] = (g[j] / 2) + currG;
  229.             out[2] = (b[j] / 2) + currB;
  230.  
  231.             //Set the final pixels
  232.             fa->setRGB(j, i, out);
  233.             fa->setAlpha(j, i, a[i]);
  234.         }
  235.         //Step the monitor every 10th line
  236.         if ((i % 10) == 0) MON_INCR (mon, 10);
  237.     }
  238.  
  239.     //Kill the monitor
  240.     MON_DONE (mon);
  241.  
  242.     return;
  243. }
  244.  
  245.  
  246. //The interface function
  247. int GRADInterface (
  248.     long        version,
  249.     GlobalFunc    *global,
  250.     LWInstance    inst,
  251.     void        *serverData
  252.     )
  253. {
  254.     //Variables used to work the 
  255.     LWPanelFuncs    *panl;
  256.     LWPanelID        panID;
  257.     
  258.     LWControl        *ctrl;
  259.     MessageFuncs    *message;
  260.  
  261.     GRADIENT *defInst = reinterpret_cast<GRADIENT *>(inst);
  262.  
  263.  
  264.     //Get the message function ready.
  265.     message = reinterpret_cast<MessageFuncs*>(global("Info Messages", GFUSE_TRANSIENT));
  266.     if (!message )
  267.         return AFUNC_BADGLOBAL;
  268.  
  269.     //Get the panel function ready.
  270.     panl = reinterpret_cast<LWPanelFuncs*>(global(PANEL_SERVICES_NAME, GFUSE_TRANSIENT));
  271.     if(!panl)
  272.     {
  273.         (*message->error)("Unable to activate global "PANEL_SERVICES_NAME, "     please add plugin lwpanels.p" );
  274.         return AFUNC_BADGLOBAL;
  275.     }
  276.  
  277.     //This creates the panel in memory.
  278.     panID = panl->create("Lightwavin' Plugin Tutorial Interface", NULL);
  279.  
  280.     //Add and set controls now.
  281.     {
  282.         RGB_CTL(panl, panID, "Color at top of image");
  283.         ctrl = panl->nextControl(panID, NULL);
  284.         SET_IVEC(ctrl, defInst->cTop[0], defInst->cTop[1], defInst->cTop[2]);
  285.     }
  286.     {
  287.         RGB_CTL(panl, panID, "Color at bottom of image");
  288.         ctrl = panl->nextControl(panID, ctrl);
  289.         SET_IVEC(ctrl, defInst->cBottom[0], defInst->cBottom[1], defInst->cBottom[2]);
  290.     }
  291.  
  292.     //This displays the panel.  It returns 0 if the user clicked cancel, 1 otherwise.
  293.     if( panl->open(panID, PANF_BLOCKING | PANF_CANCEL) )
  294.     {
  295.         ctrl = panl->nextControl(panID, NULL);
  296.         GET_IVEC(ctrl, defInst->cTop[0], defInst->cTop[1], defInst->cTop[2]);
  297.  
  298.         ctrl = panl->nextControl(panID, ctrl);
  299.         GET_IVEC(ctrl, defInst->cBottom[0], defInst->cBottom[1], defInst->cBottom[2]);
  300.     }
  301.  
  302.     //This kills the panel.
  303.     panl->destroy(panID);
  304.  
  305.     return AFUNC_OK;
  306. }